package com.qianniu.napi.admin.task;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.qianniu.napi.admin.entity.*;
import com.qianniu.napi.admin.entity.penum.PTstatus;
import com.qianniu.napi.admin.entity.penum.RefundEnum;
import com.qianniu.napi.admin.entity.penum.StatusEnum;
import com.qianniu.napi.admin.mapper.OrderStatMapper;
import com.qianniu.napi.admin.service.*;
import com.qianniu.napi.common.util.DateUtil;
import com.qianniu.napi.common.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Configuration
@Component // 此注解必加
@EnableScheduling // 此注解必加
public class OrderTask {

    private static final Logger logger = LoggerFactory.getLogger(OrderTask.class);

    @Autowired
    private IOrderService orderService;
    @Autowired
    private IOrderGoodsService orderGoodsService;
    @Autowired
    private IRedisService redisService;
    @Autowired
    private IPintuanOpenService pintuanOpenService;
    @Autowired
    private IPintuanLogService pintuanLogService;
    @Autowired
    private ICutpriceOpenService cutpriceOpenService;
    @Autowired
    private ICutpriceHelpService cutpriceHelpService;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IStoreService storeService;
    @Autowired
    private OrderStatMapper orderStatMapper;
    @Autowired
    private IMaccountService maccountService;
    @Autowired
    private IMerchantConfigService merchantConfigService;
    @Autowired
    private IMerchantAppService merchantAppService;
    @Autowired
    private IQnpay qnpay;


    @Scheduled(cron = "0 0/5 * * * ?")
    public void refreshOrderStatus() {
        logger.debug(">>>>>>>>>>>>>>>refreshStock exe success");
        List<Order> list = orderService.selectList(new EntityWrapper<Order>().eq("status", 1));
        Date now = new Date();
        Order uo;
        OrderGoods uogs;
        for (Order order : list) {
            // 超时未支付订单关闭
            if (now.getTime() - order.getCreatetime().getTime() > 29 * 60 * 1000l) {
                uo = new Order();
                uo.setId(order.getId());
                uo.setStatus(StatusEnum.close.getVal());
                uo.updateById();

                uogs = new OrderGoods();
                uogs.setStatus(StatusEnum.close.getVal());
                uogs.update(new EntityWrapper().eq("oid", order.getId()));
            }
        }

        logger.debug(">>>refreshStock exe success");
    }

    @Scheduled(cron = "0 25 0 * * ?")
    public void refreshKanjiaStatus() {
        logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>refreshKanjiaStatus exe success");

        List<CutpriceHelp> cutpriceHelplist = cutpriceHelpService.selectList(new EntityWrapper<CutpriceHelp>());
        logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>cutpriceHelplist.size=" + cutpriceHelplist.size());
        for (CutpriceHelp item : cutpriceHelplist) {
            Goods goods = goodsService.selectOne(new EntityWrapper<Goods>().setSqlSelect("id,sid").eq("id", item.getGid()));
            if (goods == null || goods.getSid() == null) continue;
            item.setSid(goods.getSid());
            item.updateById();
        }

        List<CutpriceOpen> cutpriceOpenlist = cutpriceOpenService.selectList(new EntityWrapper<CutpriceOpen>());
        logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>cutpriceOpenlist.size=" + cutpriceOpenlist.size());
        for (CutpriceOpen item : cutpriceOpenlist) {
            Goods goods = goodsService.selectOne(new EntityWrapper<Goods>().setSqlSelect("id,sid").eq("id", item.getGid()));
            if (goods == null || goods.getSid() == null) continue;

            item.setSid(goods.getSid());
            item.updateById();
        }

        logger.debug(">>>refreshStock exe success");
    }

    //@Scheduled(cron = "0 0/3 * * * ?")
    public void checkPintuanOrderRefund() {
        logger.debug(">>>>>>>>>>>>>>>>>>checkOrderRefund start");

        Integer index = 1;
        Integer limit = 100;
        boolean flag = true;
        while (flag) {

            List<Order> list = orderService.getPTOrderGoodsPage(null, index, limit, null, -1, 0);
            logger.debug(">>>>>>>>>>>>>>>>>>checkOrderRefund list=" + JSON.toJSONString(list));

            for (Order order : list) {
                logger.info("------------------------------for each start");

                OrderRefund orderrefund = new OrderRefund();
                orderrefund.setRefundNo(StringUtil.getSnNo("T"));
                orderrefund.setOid(order.getId());
                orderrefund.setOrderNo(order.getOrderNo());
                orderrefund.setRealpay(order.getRealpay());
                orderrefund.setRefund(order.getRealpay());
                orderrefund.setOgid(order.getGid());

                orderrefund.setCreatetime(new Date());
                orderrefund.setStatus(1);
                orderrefund.setState(1);

                orderrefund.setUid(order.getUid());
                orderrefund.setMid(order.getMid());
                orderrefund.setMpid(order.getMpid());
                String ip = "127.0.0.1";
                orderrefund.setIp(ip);// 赋值：  js: feedback.ip = ip

                orderrefund.setTerminal("admin");
                orderrefund.insert();
                logger.info("------------------------------orderrefund.insert()");

                Order norder = new Order();
                norder.setRefundNo(orderrefund.getRefundNo());
                norder.setId(order.getId());
                norder.updateById();
                logger.info("------------------------------norder.updateById()");

                order.setRefundNo(orderrefund.getRefundNo());
                MerchantApp ma = redisService.getMApp(order.getMpid());
                Map map = qnpay.cancelOrder(order, ma.getAppid());
                logger.info("------------------------------checkPintuanOrderRefund cancelOrder map=" + JSON.toJSONString(map));
                if (map.containsKey("code")) {
                    orderrefund.setStatus(RefundEnum.success.getVal());
                    orderrefund.updateById();
                }
            }
            flag = list != null && list.size() == limit;
            index++;
        }

        logger.debug(">>>refreshStock exe success");
    }

    @Scheduled(cron = "0 0/3 * * * ?")
    public void finishXuniPintuan() {

        List<PintuanOpen> plist = pintuanOpenService.selectList(new EntityWrapper<PintuanOpen>()
                .where("xuni = 1 and state =1 and status=1 and endtime < DATE_ADD(NOW(),INTERVAL 3 MINUTE) "));
        for (PintuanOpen item : plist) {
            int cha = item.getPtotal() - item.getPnumber();
            if (cha <= 0) continue;
            // 添加虚拟成员
            for (int i = 0; i < cha; i++) {
                PintuanLog pintuanLog = new PintuanLog();
                pintuanLog.setPtoid(item.getId());
                pintuanLog.setOid(0l);
                pintuanLog.setGid(item.getGid());
                pintuanLog.setMid(item.getMid());
                pintuanLog.setMpid(item.getMpid());
                pintuanLog.setState(1);
                pintuanLog.setAmount(1);
                pintuanLog.setCreatetime(new Date());

                pintuanLog.setUid(0l);
                pintuanLog.setPhone(null);
                User user = userService.selectOne(new EntityWrapper<User>()
                        .setSqlSelect("nick_name nickName,avatar_pic avatarPic,phone")
                        .ne("mpid", item.getMpid())
                        .isNotNull("mpid").isNotNull("avatar_pic").isNotNull("nick_name")
                );

                pintuanLog.setAvatarpic(user.getAvatarPic());
                pintuanLog.setNickname(user.getNickName());
                pintuanLog.insert();

            }
            // 更新拼团状态
            item.setPnumber(item.getPtotal());
            item.setStatus(PTstatus.ok.getVal());
            item.setSuccesstime(new Date());
            item.setModifytime(new Date());
            item.setModifier(0l);
            item.updateById();

            Order norder = new Order();
            norder.setId(item.getOid());
            norder.setStatus(StatusEnum.receving.getVal());
            norder.setModifytime(new Date());
            norder.updateById();
        }
    }

    //刷新订单统计任务
    @Scheduled(cron = "0 02 12 * * ?")
    public void freshOrderStat() {
        logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>freshOrderStat start");

        Integer index = 1;
        Integer limit = 100;
        boolean flag = true;
        String today = DateUtil.addToday(-2);
        String stoday = today.replaceAll("-", "") + "%";
        Page page = null;
        Wrapper<MerchantApp> entity = new EntityWrapper<MerchantApp>().eq("state", 1);
        while (flag) {
            page = new Page(index, limit);
            Page<MerchantApp> plist = merchantAppService.selectPage(page, entity);
            if (plist == null || plist.getRecords().size() == 0) break;

            for (MerchantApp mch : plist.getRecords()) {

                logger.info("------------------------------stattype=1 mp stat");
                Order order = orderService.selectOne(new EntityWrapper<Order>().setSqlSelect("sum(realpay) realpay")
                        .where(" mpid=" + mch.getId() + " and status>=2" + " and order_no like '" + stoday + "'"));
                int total = orderService.selectCount(new EntityWrapper<Order>().setSqlSelect("id")
                        .where(" mpid=" + mch.getId() + " and status>=2" + " and order_no like '" + stoday + "'"));

                if (order == null) {
                    order = new Order();
                    order.setRealpay(new BigDecimal(0));
                }
                ;
                logger.info("------------------------------stattype=2 mp stat");

                OrderStat orderStat = new OrderStat();
                orderStat.setMid(mch.getMid());
                orderStat.setMpid(mch.getId());
                orderStat.setStatday(today);
                orderStat.setCreatetime(new Date());

                orderStat.setMoney(order.getRealpay());
                orderStat.setTotal(total);
                orderStat.setStattype(1);
                orderStat.insert();

                logger.info("------------------------------stattype=3 mp stat");
                logger.debug(">>>>>>>>>>>>>>>>>>freshOrderStat mch.getVersion()=" + mch.getVersion());
                if (mch.getVersion() != 3 && mch.getVersion() != 4) continue;

                //计算sid平台商家
                Integer sindex = 1;
                boolean sflag = true;

                Page spage = null;
                Wrapper<Store> sentity = new EntityWrapper<Store>().eq("state", 1).eq("mpid", mch.getId());

                logger.debug(">>>>>>>>>>>>>>>>>>freshOrderStat splist 000");

                while (sflag) {
                    spage = new Page(sindex, limit);
                    Page<Store> splist = storeService.selectPage(spage, sentity);

                    logger.debug(">>>>>>>>>>>>>>>>>>freshOrderStat splist 111");
                    if (splist == null || splist.getRecords().size() == 0) break;

                    for (Store store : splist.getRecords()) {
                        logger.debug(">>>>>>>>>>>>>>>>>>freshOrderStat splist 222");

                        logger.info("------------------------------stattype=1 mp stat");
                        Order sorder = orderService.selectOne(new EntityWrapper<Order>().setSqlSelect("sum(realpay) realpay")
                                .where(" sid=" + store.getId() + " and status>=2" + " and order_no like '" + stoday + "'"));
                        int stotal = orderService.selectCount(new EntityWrapper<Order>().setSqlSelect("id")
                                .where(" sid=" + store.getId() + " and status>=2" + " and order_no like '" + stoday + "'"));

                        if (stotal == 0) continue;

                        OrderStat sorderStat = new OrderStat();
                        sorderStat.setMid(mch.getMid());
                        sorderStat.setMpid(mch.getId());
                        sorderStat.setSid(store.getId());

                        sorderStat.setStatday(today);
                        sorderStat.setCreatetime(new Date());
                        sorderStat.setMoney(sorder.getRealpay());
                        sorderStat.setTotal(stotal);
                        sorderStat.setStattype(2);
                        sorderStat.insert();

                    }

                    sflag = splist != null && splist.getRecords().size() == limit;
                    sindex++;
                }
            }

            flag = plist != null && plist.getRecords().size() == limit;
            index++;
            logger.debug(">>>>>>>>>>>>>>>>>>freshOrderStat exe success");
        }
    }

    //刷新订单自动确认收货任务
    @Scheduled(cron = "0 5 0/1 * * ?")
    public void freshOrderConfirmStatus() {
        logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>freshOrderConfirmStatus start");

        Integer index = 1;
        Integer limit = 100;
        boolean flag = true;
        Page page = null;
        Wrapper<Order> entity = new EntityWrapper<Order>()
                .eq("status", 3).eq("fhstate", 2);
        Date now = new Date();
        long nowtime = now.getTime();

        while (flag) {
            page = new Page(index, limit);
            Page<Order> list = orderService.selectPage(page, entity);
            if (list == null || list.getRecords().size() == 0) break;

            for (Order order : list.getRecords()) {
                logger.debug(">>>>>>>>>>>>>>>>>>freshOrderConfirmStatus list 000");
                MerchantConfig mconfig = redisService.getMconfig(order.getMpid());

                if (mconfig.getConfirmhours() == null || order.getFhtime() == null) continue;

                int confirmtime = mconfig.getConfirmhours() * 60 * 60 * 1000;
                if (order.getFhtime().getTime() + confirmtime > nowtime) continue;

                Order norder = new Order();
                norder.setId(order.getId());
                //支持品论就进入待评论状态
                if (mconfig.getShowCommet() != null && mconfig.getShowCommet() == 1) {
                    norder.setStatus(StatusEnum.commenting.getVal());
                } else {
                    //支持品论就进入订单完成状态
                    norder.setStatus(StatusEnum.finish.getVal());
                }
                norder.setConfirmtime(new Date());
                norder.setModifytime(new Date());
                norder.setModifier(0l);
                norder.updateById();
            }

            flag = list != null && list.getRecords().size() == limit;
            index++;
        }
        logger.debug(">>>>>>>>>>>>>>>>>>freshOrderConfirmStatus exe success");
    }

    //刷新订单自动接单任务
    @Scheduled(cron = "0 0/1 * * * ?")
    public void freshOrderAutojiedanStatus() {
        logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>freshOrderAutojiedanStatus start");

        Integer index = 1;
        Integer limit = 100;
        boolean flag = true;
        long nowtime = new Date().getTime();
        Page page = null;
        Wrapper<MerchantConfig> entity = new EntityWrapper<MerchantConfig>();
        while (flag) {
            page = new Page(index, limit);
            Page<MerchantConfig> plist = merchantConfigService.selectPage(page, entity);
            if (plist == null || plist.getRecords().size() == 0) break;

            for (MerchantConfig mconfig : plist.getRecords()) {

                logger.info("------------------------------freshOrderAutojiedanStatus start");
                //判断是否开启自动接单，单位分钟
                if (mconfig.getAutojiedan() == null || mconfig.getAutojiedan() <= 0) continue;

                int jiedantime = mconfig.getAutojiedan() * 60 * 1000;

                //计算sid平台商家
                Integer sindex = 1;
                boolean sflag = true;

                Page spage = null;
                Wrapper<Order> sentity = new EntityWrapper<Order>().eq("state", 2).eq("mpid", mconfig.getMpid());

                logger.debug(">>>>>>>>>>>>>>>>>>freshOrderStat splist 000");

                while (sflag) {
                    spage = new Page(sindex, limit);
                    Page<Order> splist = orderService.selectPage(spage, sentity);

                    if (splist == null || splist.getRecords().size() == 0) break;

                    for (Order order : splist.getRecords()) {
                        //当前时刻跟成功支付时间比较
                        if (nowtime - order.getPaytime().getTime() >= jiedantime) continue;

                        Order norder = new Order();
                        norder.setId(order.getId());

                        norder.setStatus(StatusEnum.forsend.getVal());
                        norder.setFhstate(1);

                        norder.setJdtime(new Date());
                        norder.setModifytime(new Date());
                        norder.setModifier(0l);
                        norder.updateById();

                    }

                    sflag = splist != null && splist.getRecords().size() == limit;
                    sindex++;
                }


            }
            flag = plist != null && plist.getRecords().size() == limit;
            index++;
        }

        logger.debug(">>>>>>>>>>>>>>>>>>freshOrderAutojiedanStatus exe success");
    }

    //执行周期频率 每30分钟检查一次
    //刷新对于已超时的订单，如限时拼团砍价的订单
    //在规定的时间内，没完成支付动作的
    //适用于拼团和砍价SELECT * FROM `t_user` WHERE mpid=11 and date(createtime)=date(now())
    //查询条件：
    @Scheduled(cron = "0 0/10 * * * ?")
    public void freshOrderTimeoutStatus() {
        logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>freshOrderTimeoutStatus start");

        Integer index = 1;
        Integer limit = 100;
        boolean flag = true;
        Integer total = 0;
        Date now = new Date();
        long nowtime = now.getTime();
        String nowstr= DateUtil.toDateString(now,"yyyy-MM-dd HH:mm:ss");

        int createday = Integer.parseInt(DateUtil.toDateString(DateUtil.addDay(new Date(),-3),"YYYYMMdd"));

        //砍价
        Page page = null;
        Wrapper<Order> entity = new EntityWrapper<Order>().ge("createday",createday).isNotNull("endtime")
                .addFilter("UNIX_TIMESTAMP(endtime)<=UNIX_TIMESTAMP('"+nowstr+"') ")
                .eq("status",1).eq("type",2);

        while (flag) {
            page = new Page(index, limit);
            Page<Order> plist = orderService.selectPage(page, entity);
            if (plist == null || plist.getRecords().size() == 0) break;

            for (Order item : plist.getRecords()) {
                Order norder = new Order();
                norder.setId(item.getId());
                norder.setModifytime(now);
                norder.setModifier(0l);
                norder.setStatus(StatusEnum.cancel.getVal());
                norder.updateById();
                total++;

                CutpriceOpen uCutpriceOpen = new CutpriceOpen();
                uCutpriceOpen.setModifytime(new Date());
                uCutpriceOpen.setStatus(-StatusEnum.close.getVal());

                cutpriceOpenService.update(uCutpriceOpen,new EntityWrapper<CutpriceOpen>().eq("oid",item.getId()));
            }
            flag = plist != null && plist.getRecords().size() == limit;
            index++;
        }

        logger.debug(">>>>>>>>>>>>>>>>>>freshOrderTimeoutStatus kanjia success with total="+total);

        //拼团
        index = 1;
        entity = new EntityWrapper<Order>().ge("createday",createday).isNotNull("endtime")
                .addFilter("UNIX_TIMESTAMP(endtime)<=UNIX_TIMESTAMP('"+nowstr+"') ")
                .eq("status",2).eq("type",1);

        while (flag) {
            page = new Page(index, limit);
            Page<Order> plist = orderService.selectPage(page, entity);
            if (plist == null || plist.getRecords().size() == 0) break;

            for (Order item : plist.getRecords()) {
                Order norder = new Order();
                norder.setId(item.getId());
                norder.setModifytime(now);
                norder.setModifier(0l);
                norder.setStatus(StatusEnum.cancel.getVal());
                norder.updateById();
                total++;

                PintuanOpen uPintuanOpen = new PintuanOpen();
                uPintuanOpen.setModifytime(new Date());
                uPintuanOpen.setStatus(-StatusEnum.close.getVal());

                pintuanOpenService.update(uPintuanOpen,new EntityWrapper<PintuanOpen>().eq("oid",item.getId()));
            }
            flag = plist != null && plist.getRecords().size() == limit;
            index++;
        }

        logger.debug(">>>>>>>>>>>>>>>>>>freshOrderTimeoutStatus pintuan success with total="+total);
    }

}
